package com.example.travel.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.travel.common.AjaxResult;
import com.example.travel.common.AuthAccess;
import com.example.travel.common.TableDataInfo;
import com.example.travel.domain.entity.Files;
import com.example.travel.domain.request.PageQuery;
import com.example.travel.service.FileService;
import io.swagger.annotations.Api;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * @Author : LinQingLiang
 * @file : FileController.java
 * @Since : 2023/1/26 13:06
 */

@RestController
@RequestMapping("/file")
@Api(tags = "文件管理")
public class FileController extends BaseController{

    @Value("${files.upload.path}")
    private String fileUploadPath;

//    @Value("${server.ip}")
//    private String serverIp;

    @Autowired
    private FileService fileService;

    /**
     * 文件上传接口
     * @param file  前端传递过来的文件
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public String upload(@RequestParam MultipartFile file) throws IOException {
        String originFileName = file.getOriginalFilename();
        String type = FileUtil.extName(originFileName);
        long size = file.getSize();

        //先存到磁盘

        //定义一个唯一的标识码
        String uuid = IdUtil.fastSimpleUUID();
        String fileUuid = uuid + StrUtil.DOT + type;
        File uploadFile = new File(fileUploadPath + fileUuid);

        File parentFile = uploadFile.getParentFile();
        //判断配置的文件目录是否存在，不存在就创建一个新的目录
        if (!parentFile.exists()){
            parentFile.mkdirs();
        }

        String url;
        //上传文件到磁盘
        file.transferTo(uploadFile);
        //获取文件md5
        String md5 = SecureUtil.md5(uploadFile);
        Files files = getFilesByMd5(md5);
        //获取文件的url
        if (files != null){
            url = files.getUrl();
            //由于文件以存在，所以删除刚才上传的重复文件
            uploadFile.delete();
        }else{
            //数据库若不存在重复文件，则不删除刚才上传的文件
            url = "http://127.0.0.1:8082/travel/file/"+fileUuid;
        }


        //存储到数据库
        Files saveFile = new Files();
        saveFile.setName(originFileName);
        saveFile.setSize(size/1024);
        saveFile.setType(type);
        saveFile.setUrl(url);
        saveFile.setMd5(md5);
        saveFile.setEnable(true);
        fileService.save(saveFile);
        return url;
    }


    /**
     * 文件的下载路径 http://localhost:8082/travel/file/"+fileUuid
     * @param fileUuid
     * @param response
     * @throws IOException
     */
    @GetMapping("/{fileUuid}")
    public void downLoad(@PathVariable String fileUuid, HttpServletResponse response) throws IOException {
        //根据文件的唯一标识码获取文件
        File uploadFile = new File(fileUploadPath+fileUuid);
        //设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("content-Disposition","attachment;filename=" + URLEncoder.encode(fileUuid, "UTF-8"));
        response.setContentType("application/octet-stream");

        //读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();;
        os.close();
    }


    /**
     * 通过MD5查询文件
     * @param md5
     * @return
     */
    private Files getFilesByMd5(String md5){
        LambdaQueryWrapper<Files> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(Files::getMd5,md5);
        List<Files> filesList = fileService.list(lambdaQueryWrapper);
        return filesList.size() == 0 ? null : filesList.get(0);
    }


    /**
     * 分页查询
     * @param pageQuery
     * @param name
     * @return
     */
    @GetMapping("list")
    public TableDataInfo list(@Validated PageQuery pageQuery, @Param("name") String name){
        Page page1 = fileService.page(pageQuery.getPageNum(),pageQuery.getPageSize(),name);
        return getDataTable(page1.getRecords(),page1.getTotal());
    }

    /**
     * 获取文件管理的MP4
     * @return
     */
    @AuthAccess
    @GetMapping("/list/getMp4")
    public AjaxResult getFilesList(){
        return AjaxResult.success(fileService.list());
    }

    /**
     * 删除个人
     * @param fileId
     * @return
     */
    @DeleteMapping("/{fileId}")
    public AjaxResult deleteFile(@PathVariable Integer fileId){
        Files files = fileService.getById(fileId);
        files.setDelete(true);
        return AjaxResult.success(fileService.updateById(files));
    }


    /**
     * 批量删除
     * @param fileIds
     * @return
     */
    @DeleteMapping("/deleteFiles/{fileIds}")
    public AjaxResult deleteUser(@PathVariable List<Integer> fileIds){
        QueryWrapper<Files> queryWrapper = new QueryWrapper();
        queryWrapper.in("id",fileIds).eq("is_delete",false);
        List<Files> filesList  = fileService.listByIds(fileIds);
        filesList.stream().forEach(files -> {
            files.setDelete(true);
        });
        return AjaxResult.success(fileService.updateBatchById(filesList));
    }


    /**
     *文件更新enable字段
     * @param files
     * @return
     */
    @PutMapping("/update")
    public AjaxResult updateFiles(@RequestBody Files files){
        return AjaxResult.success(fileService.updateById(files));
    }


    /**
     * 根据id查mp4记录
     * @param id
     * @return
     */
    @GetMapping("detail/{id}")
    public AjaxResult selectById(@PathVariable Integer id){
        return AjaxResult.success(fileService.getById(id));
    }
}
